package com.cskaoyan.wordmemorize.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cskaoyan.wordmemorize.converter.TopicConverter;
import com.cskaoyan.wordmemorize.dao.entity.ReviewSubTopicDO;
import com.cskaoyan.wordmemorize.dao.entity.ReviewTopicDO;
import com.cskaoyan.wordmemorize.dao.entity.TopicOptionDO;
import com.cskaoyan.wordmemorize.dao.entity.VocDO;
import com.cskaoyan.wordmemorize.dao.mapper.ReviewSubTopicMapper;
import com.cskaoyan.wordmemorize.dao.mapper.ReviewTopicMapper;
import com.cskaoyan.wordmemorize.dao.mapper.TopicOptionsMapper;
import com.cskaoyan.wordmemorize.dao.mapper.VocMapper;
import com.cskaoyan.wordmemorize.dto.admin.*;
import com.cskaoyan.wordmemorize.request.TopicCommand;
import com.cskaoyan.wordmemorize.request.VocPageRequest;
import com.cskaoyan.wordmemorize.service.TopicService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * TopicServiceImpl 是 TopicService 接口的具体实现类，负责处理单词记忆系统中题型相关的业务逻辑。
 * 包括增删改查、分页获取、Excel导入导出等功能。继承自 MyBatis-Plus 提供的 ServiceImpl，
 * 简化了基础数据访问操作。使用 ReviewTopicMapper、ReviewSubTopicMapper、TopicOptionsMapper 进行数据库操作，
 * 并通过 TopicConverter 在 DO 和 DTO 之间进行转换。
 */
@Service
public class TopicServiceImpl implements TopicService
{

    @Autowired
    private ReviewTopicMapper reviewTopicMapper;

    @Autowired
    private ReviewSubTopicMapper reviewSubTopicMapper;

    @Autowired
    private TopicOptionsMapper topicOptionsMapper;

    @Autowired
    private TopicConverter topicConverter;

    @Autowired
    private VocMapper vocMapper;

    @Override
    public VocDTO checkWord(String word)
    {
        // 重写checkWord方法，用于检查单词是否存在
        // 创建查询条件构造器
        LambdaQueryWrapper<VocDO> queryWrapper = new LambdaQueryWrapper<>();
        // 设置查询条件：单词内容等于参数word
        queryWrapper.eq(VocDO::getContent, word);
        // 执行查询，获取单词信息
        VocDO vocDO = vocMapper.selectOne(queryWrapper);

        if (vocDO != null)
        {
            // 如果单词存在，创建VocDTO对象
            VocDTO vocDTO = new VocDTO();
            // 将VocDO对象的属性复制到VocDTO对象
            BeanUtils.copyProperties(vocDO, vocDTO);
            // 返回VocDTO对象
            return vocDTO;
        }
        // 如果单词不存在，返回null
        return null;
    }

    @Override
    public PageDTO<ReviewTopicDTO> getSingleChoicePage(VocPageRequest vocPageRequest) {
        // 创建分页对象，设置当前页码和每页数量
        Page<ReviewTopicDO> page = new Page<>(vocPageRequest.getPageNum(), vocPageRequest.getCount());

        // 构建查询条件，筛选 topicType 为 1（即单选题）
        LambdaQueryWrapper<ReviewTopicDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(ReviewTopicDO::getTopicType, 1) // 筛选单选题
                .like(ReviewTopicDO::getVocabulary, vocPageRequest.getKeyword()); // 根据关键词模糊查询

        // 执行分页查询
        Page<ReviewTopicDO> result = reviewTopicMapper.selectPage(page, queryWrapper);

        // 转换为分页 DTO 返回
        return topicConverter.topicDOPage2PageDTO(result.getRecords(), result.getTotal());
    }

    /**
     * 分页获取选词填空题列表
     * @param vocPageRequest 分页请求参数
     * @return 返回选词填空题的分页结果
     */
    @Override
    public PageDTO<ReviewTopicDTO> getFillWordPage(VocPageRequest vocPageRequest) {
        // 创建分页对象
        Page<ReviewTopicDO> page = new Page<>(vocPageRequest.getPageNum(), vocPageRequest.getCount());

        // 构建查询条件，筛选 topicType 为 2（即选词填空题）
        LambdaQueryWrapper<ReviewTopicDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ReviewTopicDO::getTopicType, 2) // 筛选选词填空题
                .like(ReviewTopicDO::getVocabulary, vocPageRequest.getKeyword()); // 根据关键词模糊查询

        // 执行分页查询
        Page<ReviewTopicDO> result = reviewTopicMapper.selectPage(page, queryWrapper);
        result.getRecords().stream().forEach(reviewTopicDO -> {
            List<ReviewSubTopicDO> reviewSubTopicDOS = reviewSubTopicMapper.selectList(new LambdaQueryWrapper<ReviewSubTopicDO>().eq(ReviewSubTopicDO::getTid, reviewTopicDO.getId()).eq(ReviewSubTopicDO::getIsDeleted, 0));
            if (CollectionUtil.isNotEmpty(reviewSubTopicDOS)){
                String collect = reviewSubTopicDOS.stream().map(ReviewSubTopicDO::getVocabulary).collect(Collectors.joining(","));
                reviewTopicDO.setVocabulary(collect);
                String topics = reviewSubTopicDOS.stream().map(ReviewSubTopicDO::getTopicItem).collect(Collectors.joining(","));
                reviewTopicDO.setTopic(topics);
            }
        });

        // 转换为分页 DTO 返回
        return topicConverter.topicDOPage2PageDTO(result.getRecords(), result.getTotal());
    }


    @Override
    @Transactional
    public void addTopic(TopicCommand command)
    {
        // 将TopicCommand对象转换为ReviewTopicDO对象
        ReviewTopicDO topicDO = topicConverter.command2TopicDO(command);
        // 将ReviewTopicDO对象插入数据库
        reviewTopicMapper.insert(topicDO);

        // 如果题目类型为填空题且存在子题，则处理子题
        if (command.getTopicType() == 2 && command.getSubTopics() != null)
        {
            // 将子题命令列表转换为ReviewSubTopicDO对象列表
            List<ReviewSubTopicDO> subTopicDOs = topicConverter.commands2ReviewSubTopicDOs(command.getSubTopics());
            for (ReviewSubTopicDO subTopicDO : subTopicDOs)
            {
                // 设置子题的题目ID
                subTopicDO.setTid(topicDO.getId());
                // 将子题插入数据库
                reviewSubTopicMapper.insert(subTopicDO);
            }
        }

        // 如果存在选项，则处理选项
        if (command.getOptions() != null)
        {
            // 将选项命令列表转换为TopicOptionDO对象列表
            List<TopicOptionDO> optionDOs = topicConverter.commands2TopicDOs(command.getOptions());
            for (TopicOptionDO optionDO : optionDOs)
            {
                // 设置选项的题目ID
                optionDO.setTid(topicDO.getId());
                // 将选项插入数据库
                topicOptionsMapper.insert(optionDO);
            }
        }
    }

    @Override
    public ReviewTopicDTO getTopic(Long topicId)
    {
        // 重写getTopic方法，用于获取指定ID的题目信息
        // 从数据库中查询指定ID的题目
        ReviewTopicDO topicDO = reviewTopicMapper.selectById(topicId);
        // 如果题目不存在，则返回null
        if (topicDO == null)
        {
            return null;
        }

        // 如果题目类型为2（填空题），则处理子题
        if (topicDO.getTopicType() == 2)
        {
            // 创建查询条件构造器，用于查询子题
            LambdaQueryWrapper<ReviewSubTopicDO> subTopicWrapper = new LambdaQueryWrapper<>();
            // 设置查询条件：子题的题目ID等于参数topicId
            subTopicWrapper.eq(ReviewSubTopicDO::getTid, topicId);
            // 执行查询，获取子题列表
            List<ReviewSubTopicDO> subTopicDOs = reviewSubTopicMapper.selectList(subTopicWrapper);
            topicDO.setSubTopics(subTopicDOs);
            // 创建选项列表
            List<TopicOptionDO> options = new ArrayList<>();
            // 遍历子题列表，转换为选项
            for (ReviewSubTopicDO subTopic : subTopicDOs)
            {
                // 创建新的选项对象
                TopicOptionDO option = new TopicOptionDO();
                // 设置选项的题目ID
                option.setTid(topicId);
                // 设置选项的内容为子题的内容
                option.setItem(subTopic.getTopicItem());
                // 设置选项的序号为子题的序号
                option.setOptionNumber(subTopic.getSubTopicNumber());
                // 将选项添加到列表中
                options.add(option);
            }
            // 将选项列表设置到题目对象中
            topicDO.setOptions(options);
        }

        // 如果题目类型为1（选择题），则处理选项
        if (topicDO.getTopicType() == 1)
        {
            // 创建查询条件构造器，用于查询选项
            LambdaQueryWrapper<TopicOptionDO> optionWrapper = new LambdaQueryWrapper<>();
            // 设置查询条件：选项的题目ID等于参数topicId
            optionWrapper.eq(TopicOptionDO::getTid, topicId);
            // 执行查询，获取选项列表
            List<TopicOptionDO> optionDOs = topicOptionsMapper.selectList(optionWrapper);
            // 将选项列表设置到题目对象中
            topicDO.setOptions(optionDOs);
        }

        // 将题目对象转换为DTO对象，并返回
        return topicConverter.reviewTopicDO2DTO(topicDO);
    }

    @Override
    @Transactional
    public void updateTopic(TopicCommand command)
    {
        // 将命令对象转换为题目数据对象
        ReviewTopicDO topicDO = topicConverter.command2TopicDO(command);
        // 更新题目信息
        reviewTopicMapper.updateById(topicDO);

        // 如果题目类型为2（填空题）且存在子题信息，则处理子题
        if (command.getTopicType() == 2 && command.getSubTopics() != null)
        {
            // 创建查询条件构造器，用于删除现有的子题
            command.getSubTopics().stream().forEach(subTopicCommand -> {
                if (subTopicCommand.getId() != null){
                    reviewSubTopicMapper.deleteById(subTopicCommand.getId());
                }
            });

            // 将子题命令列表转换为子题数据对象列表
            List<ReviewSubTopicDO> subTopicDOs = topicConverter.commands2ReviewSubTopicDOs(command.getSubTopics());
            // 遍历子题数据对象列表，并插入新的子题
            for (ReviewSubTopicDO subTopicDO : subTopicDOs)
            {
                subTopicDO.setId(null);
                subTopicDO.setTid(topicDO.getId());
                reviewSubTopicMapper.insert(subTopicDO);
            }
        }

        // 如果存在选项信息，则处理选项
        if (command.getOptions() != null)
        {
            // 创建查询条件构造器，用于删除现有的选项
            command.getOptions().stream().forEach(topicOptionCommand -> {
                if (topicOptionCommand.getId() != null){
                    topicOptionsMapper.deleteById(topicOptionCommand.getId());
                }
            });

            // 将选项命令列表转换为选项数据对象列表
            List<TopicOptionDO> optionDOs = topicConverter.commands2TopicDOs(command.getOptions());
            // 遍历选项数据对象列表，并插入新的选项
            for (TopicOptionDO optionDO : optionDOs)
            {
                optionDO.setId(null);
                optionDO.setTid(topicDO.getId());
                topicOptionsMapper.insert(optionDO);
            }
        }
    }

    @Override
    @Transactional
    public DeleteTopicOperateDTO deleteTopic(Long topicId, Integer topicType)
    {
        // 查询题目信息
        ReviewTopicDO topicDO = reviewTopicMapper.selectById(topicId);
        // 如果题目不存在，则返回null
        if (topicDO == null)
        {
            return null;
        }

        // 如果题目类型为2（填空题），则删除其子题
        if (topicType!= null && topicType == 2)
        {
            // 创建查询条件构造器，用于删除子题
            LambdaQueryWrapper<ReviewSubTopicDO> subTopicWrapper = new LambdaQueryWrapper<>();
            subTopicWrapper.eq(ReviewSubTopicDO::getTid, topicId);
            reviewSubTopicMapper.delete(subTopicWrapper);
        }

        // 创建查询条件构造器，用于删除选项
        LambdaQueryWrapper<TopicOptionDO> optionWrapper = new LambdaQueryWrapper<>();
        optionWrapper.eq(TopicOptionDO::getTid, topicId);
        topicOptionsMapper.delete(optionWrapper);

        // 删除题目
        reviewTopicMapper.deleteById(topicId);

        // 将题目数据对象转换为删除题目操作DTO，并返回
        return topicConverter.topicDO2DeleteTopicDTO(topicDO);
    }

    @Override
    public void topicExcelValidate(String type, MultipartFile file) throws IOException
    {
        // 根据题目类型进行Excel验证
        if ("singleChoice".equals(type))
        {
            // 如果是单选题，使用EasyExcel读取Excel文件，并使用SingleTopicExcelDTO类作为数据模型
            EasyExcel.read(file.getInputStream(), SingleTopicExcelDTO.class, new AnalysisEventListener<SingleTopicExcelDTO>()
            {
                @Override
                public void invoke(SingleTopicExcelDTO data, AnalysisContext context)
                {
                    // 对每一行数据进行单选题验证
                    validateSingleTopic(data);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context)
                {
                    // 所有数据解析完成后执行的方法（这里为空）
                }
            }).sheet().doRead();
        } else if ("fillWord".equals(type))
        {
            // 如果是填空题，使用EasyExcel读取Excel文件，并使用FillTopicExcelDTO类作为数据模型
            EasyExcel.read(file.getInputStream(), FillTopicExcelDTO.class, new AnalysisEventListener<FillTopicExcelDTO>()
            {
                @Override
                public void invoke(FillTopicExcelDTO data, AnalysisContext context)
                {
                    // 对每一行数据进行填空题验证
                    validateFillTopic(data);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context)
                {
                    // 所有数据解析完成后执行的方法（这里为空）
                }
            }).sheet().doRead();
        }
    }

    @Override
    @Transactional
    public ExcelAddOperateDTO addSingleChoiceExcel(MultipartFile file, Long employeeId) throws IOException
    {
        // 创建Excel操作结果DTO，并设置文件名
        ExcelAddOperateDTO excelAddOperateDTO = new ExcelAddOperateDTO();
        excelAddOperateDTO.setFileName(file.getOriginalFilename());

        // 使用EasyExcel读取Excel文件，并使用SingleTopicExcelDTO类作为数据模型
        EasyExcel.read(file.getInputStream(), SingleTopicExcelDTO.class, new AnalysisEventListener<SingleTopicExcelDTO>()
        {
            private int count = 0; // 计数器，用于记录成功添加的题目数量

            @Override
            public void invoke(SingleTopicExcelDTO data, AnalysisContext context)
            {
                // 对每一行数据进行单选题验证
                validateSingleTopic(data);

                // 构建查询条件，检查题目是否已存在
                LambdaQueryWrapper<ReviewTopicDO> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(ReviewTopicDO::getTopic, data.getTopic());
                ReviewTopicMapper reviewTopicMapper1 = reviewTopicMapper;
                reviewTopicMapper1.selectOne(queryWrapper);
                if (reviewTopicMapper1 == null)
                {
                    throw new RuntimeException("topic不存在: " + data.getTopic());
                }

                // 将Excel数据转换为题目数据对象
                ReviewTopicDO topicDO = topicConverter.singleTopicExcelDTO2DO(data, null);
                switch (data.getAnswerIndex()){
                    case "A":
                        topicDO.setVocabulary(data.getOption1());
                        break;
                    case "B":
                        topicDO.setVocabulary(data.getOption2());
                        break;
                    case "C":
                        topicDO.setVocabulary(data.getOption3());
                        break;
                    case "D":
                        topicDO.setVocabulary(data.getOption4());
                        break;
                }
                reviewTopicMapper.insert(topicDO);

                // 创建选项列表
                List<TopicOptionDO> options = new ArrayList<>();
                int answerIndex = convertAnswerToIndex(data.getAnswerIndex().toString());
                options.add(createOption(topicDO.getId(), data.getOption1(), 1, answerIndex == 1));
                options.add(createOption(topicDO.getId(), data.getOption2(), 2, answerIndex == 2));
                options.add(createOption(topicDO.getId(), data.getOption3(), 3, answerIndex == 3));
                options.add(createOption(topicDO.getId(), data.getOption4(), 4, answerIndex == 4));

                // 插入选项数据
                for (TopicOptionDO option : options)
                {
                    topicOptionsMapper.insert(option);
                }

                count++; // 成功添加题目计数
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context)
            {
                // 所有数据解析完成后，设置总计数
                excelAddOperateDTO.setTotalCount(count);
            }
        }).sheet().doRead();

        // 返回Excel操作结果DTO
        return excelAddOperateDTO;
    }

    @Override
    @Transactional
    public ExcelAddOperateDTO addFillWordExcel(MultipartFile file, Long employeeId) throws IOException
    {
        // 创建Excel操作结果DTO对象
        ExcelAddOperateDTO excelAddOperateDTO = new ExcelAddOperateDTO();
        // 设置文件名
        excelAddOperateDTO.setFileName(file.getOriginalFilename());

        // 使用EasyExcel读取Excel文件，并使用FillTopicExcelDTO类作为数据模型
        EasyExcel.read(file.getInputStream(), FillTopicExcelDTO.class, new AnalysisEventListener<FillTopicExcelDTO>()
        {
            // 计数器，用于记录成功添加的题目数量
            private int count = 0;

            @Override
            public void invoke(FillTopicExcelDTO data, AnalysisContext context)
            {
                // 验证填空题数据
                validateFillTopic(data);

                // 创建题目记录
                ReviewTopicDO topicDO = new ReviewTopicDO();
                // 设置题目类型为填空题
                topicDO.setTopicType(2);

                List<String> topicsList = new ArrayList<>();
                topicsList.add(data.getSubTopic1());
                topicsList.add(data.getSubTopic2());
                topicsList.add(data.getSubTopic3());
                topicDO.setTopic(CollectionUtil.join(topicsList, ","));


                List<String> answerList = new ArrayList<>();
                answerList.add(data.getAnswer1());
                answerList.add(data.getAnswer2());
                answerList.add(data.getAnswer3());
                topicDO.setVocabulary(CollectionUtil.join(answerList, ","));

                // 插入题目记录
                reviewTopicMapper.insert(topicDO);

                // 创建子题列表
                List<ReviewSubTopicDO> subTopics = new ArrayList<>();
                // 添加子题1
                subTopics.add(createSubTopic(topicDO.getId(), data.getSubTopic1(), data.getAnswer1(), 1));
                // 添加子题2
                subTopics.add(createSubTopic(topicDO.getId(), data.getSubTopic2(), data.getAnswer2(), 2));
                // 添加子题3
                subTopics.add(createSubTopic(topicDO.getId(), data.getSubTopic3(), data.getAnswer3(), 3));

                // 插入子题记录
                for (ReviewSubTopicDO subTopic : subTopics)
                {
                    reviewSubTopicMapper.insert(subTopic);
                }

                // 创建选项记录
                TopicOptionDO option = new TopicOptionDO();
                // 设置题目ID
                option.setTid(topicDO.getId());
                // 设置选项内容
                option.setItem(data.getError());
                // 设置是否为正确答案
                option.setIsAnswer(0);
                // 设置选项序号
                option.setOptionNumber(1);
                // 插入选项记录
                topicOptionsMapper.insert(option);

                // 增加计数器
                count++;
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context)
            {
                // 所有数据解析完成后，设置总计数
                excelAddOperateDTO.setTotalCount(count);
            }
        }).sheet().doRead();

        // 返回Excel操作结果DTO
        return excelAddOperateDTO;
    }

    @Override
    @Transactional
    public DeleteSubTopicOperateDTO deleteSubTopic(Long id)
    {
        // 根据ID查询子题信息
        ReviewSubTopicDO subTopicDO = reviewSubTopicMapper.selectById(id);
        // 如果子题不存在，返回null
        if (subTopicDO == null)
        {
            return null;
        }

        // 删除子题记录
        reviewSubTopicMapper.deleteById(id);

        // 将子题信息转换为删除子题操作DTO，并返回
        return topicConverter.toDeleteSubTopicDTO(subTopicDO);
    }

    @Override
    @Transactional
    public DeleteTopicOptionOperateDTO deleteTopicOption(Long id)
    {
        // 根据ID查询选项信息
        TopicOptionDO optionDO = topicOptionsMapper.selectById(id);
        // 如果选项不存在，返回null
        if (optionDO == null)
        {
            return null;
        }

        // 根据选项的题目ID查询题目信息
        ReviewTopicDO topicDO = reviewTopicMapper.selectById(optionDO.getTid());

        // 删除选项记录
        topicOptionsMapper.deleteById(id);

        // 将选项信息和题目信息转换为删除题目选项操作DTO，并返回
        return topicConverter.toDeleteTopicOptionDTO(optionDO, topicDO.getTopic());
    }


    private int convertAnswerToIndex(String answer)
    {
        if (answer == null || answer.trim().isEmpty())
        {
            throw new RuntimeException("答案不能为空");
        }
        String upperAnswer = answer.trim().toUpperCase();
        switch (upperAnswer)
        {
            case "A":
                return 1;
            case "B":
                return 2;
            case "C":
                return 3;
            case "D":
                return 4;
            default:
                throw new RuntimeException("答案必须是A、B、C、D中的一个");
        }
    }


    private void validateSingleTopic(SingleTopicExcelDTO data)
    {
        if (data.getTopic() == null || data.getTopic().trim().isEmpty())
        {
            throw new RuntimeException("题目不能为空");
        }
        if (data.getOption1() == null || data.getOption1().trim().isEmpty())
        {
            throw new RuntimeException("选项1不能为空");
        }
        if (data.getOption2() == null || data.getOption2().trim().isEmpty())
        {
            throw new RuntimeException("选项2不能为空");
        }
        if (data.getOption3() == null || data.getOption3().trim().isEmpty())
        {
            throw new RuntimeException("选项3不能为空");
        }
        if (data.getOption4() == null || data.getOption4().trim().isEmpty())
        {
            throw new RuntimeException("选项4不能为空");
        }
        if (data.getAnswerIndex() == null || data.getAnswerIndex().toString().trim().isEmpty())
        {
            throw new RuntimeException("答案不能为空");
        }
//        String upperAnswer = data.getAnswerIndex().toString().trim().toUpperCase();
//        if (!(upperAnswer.contains(data.getOption1()) || upperAnswer.contains(data.getOption2()) || upperAnswer.contains(data.getOption3()) || upperAnswer.contains(data.getOption4())))
//        {
//            throw new RuntimeException("答案必须是A、B、C、D中的一个");
//        }
    }

    private void validateFillTopic(FillTopicExcelDTO data)
    {
        if (data.getSubTopic1() == null || data.getSubTopic1().trim().isEmpty())
        {
            throw new RuntimeException("小题1不能为空");
        }
        if (data.getAnswer1() == null || data.getAnswer1().trim().isEmpty())
        {
            throw new RuntimeException("答案1不能为空");
        }
        if (data.getSubTopic2() == null || data.getSubTopic2().trim().isEmpty())
        {
            throw new RuntimeException("小题2不能为空");
        }
        if (data.getAnswer2() == null || data.getAnswer2().trim().isEmpty())
        {
            throw new RuntimeException("答案2不能为空");
        }
        if (data.getSubTopic3() == null || data.getSubTopic3().trim().isEmpty())
        {
            throw new RuntimeException("小题3不能为空");
        }
        if (data.getAnswer3() == null || data.getAnswer3().trim().isEmpty())
        {
            throw new RuntimeException("答案3不能为空");
        }
        if (data.getError() == null || data.getError().trim().isEmpty())
        {
            throw new RuntimeException("干扰项不能为空");
        }
    }


    /**
     * 创建一个新的题目选项记录
     *
     * @param topicId      题目的ID，用于关联题目和选项
     * @param item         选项的内容，例如选项A、选项B等
     * @param optionNumber 选项的序号，例如1表示第一个选项
     * @param isAnswer     是否为正确答案，true表示是，false表示否
     * @return 返回创建的TopicOptionDO对象
     */
    private TopicOptionDO createOption(Long topicId, String item, Integer optionNumber, boolean isAnswer)
    {
        // 创建一个新的TopicOptionDO对象
        TopicOptionDO option = new TopicOptionDO();
        // 设置题目ID
        option.setTid(topicId);
        // 设置选项内容
        option.setItem(item);
        // 设置是否为正确答案，1表示是，0表示否
        option.setIsAnswer(isAnswer ? 1 : 0);
        // 设置选项序号
        option.setOptionNumber(optionNumber);
        // 返回创建的选项对象
        return option;
    }

    /**
     * 创建一个新的子题记录
     *
     * @param topicId        题目的ID，用于关联题目和子题
     * @param topicItem      子题的内容，例如子题的具体描述或问题
     * @param vocabulary     子题中涉及到的词汇或术语
     * @param subTopicNumber 子题的序号，例如1表示第一个子题
     * @return 返回创建的ReviewSubTopicDO对象
     */
    private ReviewSubTopicDO createSubTopic(Long topicId, String topicItem, String vocabulary, Integer subTopicNumber)
    {
        // 创建一个新的ReviewSubTopicDO对象
        ReviewSubTopicDO subTopic = new ReviewSubTopicDO();
        // 设置题目ID
        subTopic.setTid(topicId);
        // 设置子题内容
        subTopic.setTopicItem(topicItem);
        // 设置子题中涉及到的词汇或术语
        subTopic.setVocabulary(vocabulary);
        // 设置子题序号
        subTopic.setSubTopicNumber(subTopicNumber);
        // 返回创建的子题对象
        return subTopic;
    }

}
